package de.szut.util;

/**
 * Serves as a return type for methods that are fallible.
 * Fallible methods often can either return only the resulting value OR if the operation succeeded.
 * This data loss is being solved by Fallible serving as a return type containing both, the value and the information if the operation succeeded.
 * @author Marc Huisinga
 *
 * @param <T> Type to store
 */
public class Fallible<T> implements Restitution<T> {
	
	private T content;
	private boolean succeeded;
	
	/**
	 * Constructor
	 * @param content - Content to store
	 * @param succeeded - Operation succeeded
	 */
	public Fallible(boolean succeeded, T content) {
		this.content = content;
		this.succeeded = succeeded;
	}

	/**
	 * Gets the content stored in Fallible
	 * @return content
	 */
	public T getContent() {
		return content;
	}
	
	/**
	 * Sets the content stored in fallible
	 * @param content - content to store
	 */
	public void setContent(T content) {
		this.content = content;
	}

	/**
	 * Gets if the operation succeeded
	 * @return operation succeeded
	 */
	public boolean hasSucceeded() {
		return succeeded;
	}

	/**
	 * Sets if the operation succeeded
	 * @param succeeded true if the operation succeeded and false if it did not succeed
	 */
	public void setSucceeded(boolean succeeded) {
		this.succeeded = succeeded;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((content == null) ? 0 : content.hashCode());
		result = prime * result + (succeeded ? 1231 : 1237);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Fallible)) {
			return false;
		}
		Fallible<?> other = (Fallible<?>) obj;
		if (content == null) {
			if (other.content != null) {
				return false;
			}
		} else if (!content.equals(other.content)) {
			return false;
		}
		if (succeeded != other.succeeded) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Fallible [content=");
		builder.append(content);
		builder.append(", succeeded=");
		builder.append(succeeded);
		builder.append("]");
		return builder.toString();
	}
}
